package com.clockey.server.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.clockey.server.constant.ErrorCode;
import com.clockey.server.dao.EventInviteMappper;
import com.clockey.server.dao.EventMapper;
import com.clockey.server.dao.EventParticipantMapper;
import com.clockey.server.dao.EventPublisherMapper;
import com.clockey.server.dao.LabelEventRelMapper;
import com.clockey.server.dao.LabelMapper;
import com.clockey.server.dao.UserMapper;
import com.clockey.server.enums.HandleResult;
import com.clockey.server.pojo.Event;
import com.clockey.server.pojo.EventInvite;
import com.clockey.server.pojo.EventParticipant;
import com.clockey.server.pojo.EventPublisher;
import com.clockey.server.pojo.LabelEventRel;
import com.clockey.server.pojo.User;
import com.clockey.server.service.EventService;
import com.clockey.server.util.DateUtil;

@Service
public class EventServiceImpl implements EventService {

	@Autowired
	private EventMapper eventMapper;

	@Autowired
	private EventPublisherMapper eventPublisherMapper;

	@Autowired
	private LabelMapper labelMapper;

	@Autowired
	private LabelEventRelMapper labelEventRelMapper;

	@Autowired
	private EventParticipantMapper eventParticipantMapper;

	@Autowired
	private EventInviteMappper eventInviteMappper;

	@Autowired
	private UserMapper userMapper;

	@Override
	public JSONArray getEventsByCondition(Map<String, Object> map) {
		List<Event> events = eventMapper.list(map);
		JSONArray result = new JSONArray();
		if (events != null && !events.isEmpty()) {
			for (Event event : events) {
				JSONObject jsonObject = getBaseEvent(event);
				result.add(jsonObject);
			}
		}
		return result;
	}

	@SuppressWarnings("unchecked")
	@Override
	public void publishEvent(Map<String, Object> map) {
		Event event = (Event) map.get("event");
		eventMapper.insert(event);
		long eventId = event.getId();
		long userId = (long) map.get("userId");
		EventPublisher eventPublisher = new EventPublisher();
		eventPublisher.setEventId(eventId);
		eventPublisher.setUserId(userId);
		eventPublisherMapper.insert(eventPublisher);
		ArrayList<Long> labelIds = (ArrayList<Long>) map.get("labelIds");
		List<LabelEventRel> labelEventRels = new ArrayList<LabelEventRel>();
		for (long labelId : labelIds) {
			LabelEventRel labelEventRel = new LabelEventRel();
			labelEventRel.setEventId(labelId);
			labelEventRel.setLabelId(labelId);
			labelEventRels.add(labelEventRel);
		}
		labelEventRelMapper.batchInsert(labelEventRels);
		ArrayList<Long> inviteUserIds = (ArrayList<Long>) map.get("labelIds");
		if (inviteUserIds != null) {
			List<EventInvite> eventInvites = new ArrayList<EventInvite>();
			for (long inviteUserId : inviteUserIds) {
				EventInvite eventInvite = new EventInvite();
				eventInvite.setEventId(eventId);
				eventInvite.setHandUserId(inviteUserId);
				eventInvites.add(eventInvite);
			}
			eventInviteMappper.batchInsert(eventInvites);
			// todo发推送给受邀请者
		}
	}

	@Override
	public JSONArray getPublisherEventsByUserId(Map<String, Object> map) {
		JSONArray result = new JSONArray();
		List<Long> eventIds = eventPublisherMapper.selectListByUserId(map);
		if (eventIds != null && !eventIds.isEmpty()) {
			List<Event> events = eventMapper.listByids(eventIds);
			if (events != null && !events.isEmpty()) {
				for (Event event : events) {
					JSONObject jsonObject = getBaseEvent(event);
					result.add(jsonObject);
				}
			}
		}
		return result;
	}

	@Override
	public JSONArray getParticipantEventsByUserId(Map<String, Object> map) {
		JSONArray result = new JSONArray();
		List<EventParticipant> eventParticipants = eventParticipantMapper
				.list(map);
		if (eventParticipants != null && !eventParticipants.isEmpty()) {
			List<Long> eventIds = new ArrayList<Long>();
			for (EventParticipant eventParticipant : eventParticipants) {
				eventIds.add(eventParticipant.getEventId());
			}
			List<Event> events = eventMapper.listByids(eventIds);
			if (events != null && !events.isEmpty()) {
				for (Event event : events) {
					JSONObject jsonObject = getBaseEvent(event);
					JSONArray eventParticipantArray = getEventParticipantsByEventId(event
							.getId());
					jsonObject.put("eventParticipants", eventParticipantArray);
					result.add(jsonObject);
				}
			}
		}
		return result;
	}

	private JSONObject getBaseEvent(Event event) {
		JSONObject result = null;
		if (event != null) {
			long id = event.getId();
			result = new JSONObject();
			result.put("beginTime", event.getBeginTime());
			result.put("icon", event.getIcon());
			result.put("id", id);
			result.put("participantLimit", event.getParticipantLimit());
			result.put("content", event.getContent());
			List<String> names = labelMapper.selectLabelNameByEventId(id);
			JSONArray jsonArray = new JSONArray();
			for (String name : names) {
				jsonArray.add(name);
			}
			result.put("labelNames", jsonArray);
			result.put("alternateNum", event.getAlternateNum());
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("eventId", id);
			int participantNum = eventParticipantMapper.count(map);
			result.put("participantNum", participantNum);

		}
		return result;
	}

	public JSONArray getEventParticipantsByEventId(long eventId) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("eventId", eventId);
		List<EventParticipant> eventParticipants = eventParticipantMapper
				.list(map);
		JSONArray participants = new JSONArray();
		if (eventParticipants != null && !eventParticipants.isEmpty()) {
			for (EventParticipant eventParticipant : eventParticipants) {
				JSONObject jsonObject = new JSONObject();
				jsonObject.put("participantTime", DateUtil.format(
						eventParticipant.getCreateTime(),
						DateUtil.YYYY_MM_DD_HH_MM_SS));
				long userId = eventParticipant.getParticipantUserId();
				User user = userMapper.select(userId);
				if (user != null) {
					JSONObject userObject = new JSONObject();
					userObject.put("userId", user.getId());
					userObject.put("userName", user.getUserName());
					userObject.put("avatar", user.getAvatar());
					userObject.put("phone", user.getPhone());
					userObject.put("cid", user.getCid());
					participants.add(userObject);
				}
			}
		}
		return participants;
	}

	private JSONObject getEventPublish(long id) {
		JSONObject result = new JSONObject();
		EventPublisher eventPublish = eventPublisherMapper.select(id);
		User user = userMapper.select(eventPublish.getUserId());
		result.put("publishName", user.getUserName());
		result.put("publishAvatar", user.getAvatar());
		return result;
	}

	@Override
	public JSONObject getEventById(Map<String, Object> map) {
		Long id = (Long) map.get("id");
		Event event = eventMapper.select(id);
		JSONObject result = getBaseEvent(event);
		if (result != null) {
			JSONArray eventParticipants = getEventParticipantsByEventId(id);
			result.put("eventParticipants", eventParticipants);
			JSONObject jsonObject = getEventPublish(id);
			result.put("eventPublish", jsonObject);
		}
		return result;
	}

	@Override
	public void handEventByInviter(Map<String, Object> map) {
		long inviteUserId = (long) map.get("userId");
		long eventId = (long) map.get("eventId");
		int handResult = (int) map.get("handResult");
		eventInviteMappper.update(map);
		if (HandleResult.APPROVE.getResult() == handResult) {
			EventParticipant eventParticipant = new EventParticipant();
			eventParticipant.setEventId(eventId);
			eventParticipant.setParticipantUserId(inviteUserId);
			eventParticipantMapper.insert(eventParticipant);
			eventInviteMappper.delete(map);
			// 推送给活动发布者
		}

	}

	@Override
	public void deleteInviterByPublisher(Map<String, Object> map) {
		eventInviteMappper.delete(map);
	}

	@Override
	public void deleteParticipanterByPublisher(Map<String, Object> map) {
		eventParticipantMapper.delete(map);
	}

	@Override
	public int participantEvent(Map<String, Object> map) {
		int result = ErrorCode.FAIL;
		long eventId = (long) map.get("eventId");
		Event event = eventMapper.select(eventId);
		if (event != null) {
			int participantLimit = event.getParticipantLimit();
			int total = eventParticipantMapper.count(map);
			if (total < participantLimit) {
				EventParticipant eventParticipant = new EventParticipant();
				eventParticipant.setEventId(eventId);
				eventParticipant.setParticipantUserId((Long) map.get("userId"));
				eventParticipantMapper.insert(eventParticipant);
				result = ErrorCode.SUCCESS;
			} else {
				result = ErrorCode.PARTICIPANTEREXCEED;
			}
		}
		return result;
	}
}
